from PySide6.QtWidgets import QTableView, QHeaderView, QMenu, QMessageBox
from PySide6.QtCore import Qt, QSortFilterProxyModel, Signal, QModelIndex
from PySide6.QtGui import QKeySequence, QShortcut, QAction
from typing import List, Optional

from PySide6.QtCore import QModelIndex, QPoint, QSortFilterProxyModel, Qt
from PySide6.QtGui import QAction, QColor, QKeySequence, QShortcut
from PySide6.QtWidgets import (QAbstractItemView, QCheckBox, QComboBox,
                               QDialog, QDialogButtonBox, QFileDialog,
                               QFormLayout, QGroupBox, QHBoxLayout, QHeaderView,
                               QLabel, QLineEdit, QMenu, QMessageBox,
                               QPushButton, QSpinBox, QTableView, QVBoxLayout,
                               QWidget)

from src.frontend.table_model import TableModel


class TableView(QTableView):
    """表格视图 - 与数据管理器集成"""
    
    # 信号定义（保持向后兼容）
    cell_edited = Signal(int, int, str)  # row, col, new_value
    row_deleted = Signal(int)  # row_index
    column_moved = Signal(int, int, int)  # logical_index, old_visual_index, new_visual_index
    row_status_changed = Signal(list, str)  # row_indices, action (disable/enable)
    add_row_requested = Signal()  # 请求添加行
    insert_row_requested = Signal(int, list)  # 请求插入行，参数是位置和行数据
    delete_rows_requested = Signal(list)  # 请求删除行，参数是选中的行列表
    
    def __init__(self):
        super().__init__()
        self._model: Optional[TableModel] = None
        self._proxy_model: Optional[QSortFilterProxyModel] = None
        self._column_range: List[int] = []  # 显示的列范围
        self._setup_ui()
        self._setup_shortcuts()
        self._setup_context_menu()
        
    def _setup_ui(self):
        """设置UI"""
        # 设置表头
        self.horizontalHeader().setSectionsMovable(True)
        self.horizontalHeader().sectionMoved.connect(self._on_section_moved)
        self.horizontalHeader().setDefaultSectionSize(100)
        self.horizontalHeader().setMinimumSectionSize(50)
        self.horizontalHeader().setSectionResizeMode(QHeaderView.Interactive)
        
        # 设置垂直表头
        self.verticalHeader().setVisible(True)
        self.verticalHeader().setDefaultSectionSize(25)
        self.verticalHeader().setMinimumSectionSize(20)
        
        # 设置选择模式
        self.setSelectionBehavior(QTableView.SelectRows)
        self.setSelectionMode(QTableView.ExtendedSelection)
        
        # 设置编辑模式
        self.setEditTriggers(QTableView.DoubleClicked | QTableView.EditKeyPressed)
        
        # 设置交替行颜色
        self.setAlternatingRowColors(True)
        
        # 设置网格线
        self.setShowGrid(True)
        self.setGridStyle(Qt.SolidLine)
        
        # 启用滚动条
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        
        # 设置滚动模式
        self.setVerticalScrollMode(QTableView.ScrollPerPixel)
        self.setHorizontalScrollMode(QTableView.ScrollPerPixel)
        
        # 确保TableView能够接收键盘事件
        self.setFocusPolicy(Qt.StrongFocus)
        self.setFocus()
        
    def _setup_shortcuts(self):
        """设置快捷键"""
        # 删除行
        delete_shortcut = QShortcut(QKeySequence.Delete, self)
        delete_shortcut.activated.connect(self._delete_selected_rows)
        
        # 复制 - 移除局部快捷键，改为在主窗口处理
        # copy_shortcut = QShortcut(QKeySequence.Copy, self)
        # copy_shortcut.activated.connect(self._copy_selection)
        
        # 粘贴
        paste_shortcut = QShortcut(QKeySequence.Paste, self)
        paste_shortcut.activated.connect(self._paste_selection)
        
        # 全选
        select_all_shortcut = QShortcut(QKeySequence.SelectAll, self)
        select_all_shortcut.activated.connect(self.selectAll)
        
    def _setup_context_menu(self):
        """设置右键菜单"""
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self._show_context_menu)
        
    def set_model(self, model: TableModel):
        """设置模型"""
        self._model = model
        
        # 创建代理模型
        self._proxy_model = QSortFilterProxyModel()
        self._proxy_model.setSourceModel(model)
        self._proxy_model.setDynamicSortFilter(True)
        
        # 设置代理模型
        super().setModel(self._proxy_model)
        model.set_proxy_model(self._proxy_model)
        
        # 调整列宽
        self._adjust_column_widths()
        
        # 强制刷新表头
        self.horizontalHeader().reset()
        self.horizontalHeader().setVisible(True)
        
        # 确保滚动条可见
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        
        # 更新视图
        self.viewport().update()
        
    def _adjust_column_widths(self):
        """调整列宽"""
        if not self._model:
            return
            
        data, headers = self._model._data_manager.get_data()
        
        # 获取要显示的列
        if self._column_range:
            display_columns = self._column_range
        else:
            column_order = self._model._data_manager.get_column_order()
            display_columns = column_order
        
        for col, actual_col in enumerate(display_columns):
            if actual_col >= len(headers):
                continue
                
            header = headers[actual_col]
            
            # 计算列宽
            max_width = len(header) * 10  # 基于标题长度
            
            # 检查前100行数据
            for row in range(min(100, len(data))):
                if actual_col < len(data[row]):
                    cell_width = len(str(data[row][actual_col])) * 8
                    max_width = max(max_width, cell_width)
            
            # 设置列宽
            if self._proxy_model:
                self.setColumnWidth(col, min(max_width + 20, 300))
            else:
                self.setColumnWidth(col, min(max_width + 20, 300))
    
    def _on_section_moved(self, logical_index: int, old_visual_index: int, new_visual_index: int):
        """列移动事件"""
        # 通过事件总线发布事件
        # 注意：这里仍然保留信号发射，以保持与现有代码的兼容性
        # 在完全迁移到事件驱动架构后，可以移除信号
        self.column_moved.emit(logical_index, old_visual_index, new_visual_index)
    
    def _delete_selected_rows(self):
        """删除选中的行"""
        if not self._model:
            return
            
        selected_rows = set()
        for index in self.selectedIndexes():
            if self._proxy_model:
                source_row = self._proxy_model.mapToSource(index).row()
            else:
                source_row = index.row()
            selected_rows.add(source_row)
        
        if not selected_rows:
            return
            
        # 确认删除
        reply = QMessageBox.question(
            self, 
            "确认删除", 
            f"确定要删除选中的 {len(selected_rows)} 行吗？",
            QMessageBox.Yes | QMessageBox.No,
            QMessageBox.No
        )
        
        if reply == QMessageBox.Yes:
            # 发送信号给主窗口处理删除
            # 注意：这里仍然保留信号发射，以保持与现有代码的兼容性
            # 在完全迁移到事件驱动架构后，可以直接调用数据管理器的方法
            self.delete_rows_requested.emit(sorted(list(selected_rows), reverse=True))
    
    def _copy_selection(self):
        """复制选中内容"""
        if not self._model:
            return
            
        # 获取选中的索引
        selected_indexes = self.selectedIndexes()
        if not selected_indexes:
            return
            
        # 获取源模型索引
        source_indexes = []
        for index in selected_indexes:
            if self._proxy_model:
                source_index = self._proxy_model.mapToSource(index)
                source_indexes.append(source_index)
            else:
                source_indexes.append(index)
        
        if not source_indexes:
            return
            
        # 获取数据
        data, headers = self._model._data_manager.get_data()
        
        # 按行列组织数据
        rows_data = {}
        for index in source_indexes:
            row = index.row()
            col = index.column()
            if row < len(data) and col < len(data[row]):
                if row not in rows_data:
                    rows_data[row] = {}
                rows_data[row][col] = str(data[row][col])
        
        if not rows_data:
            return
            
        # 获取选中的行列范围
        selected_rows = sorted(rows_data.keys())
        selected_cols = sorted(set(col for row_data in rows_data.values() for col in row_data.keys()))
        
        # 创建CSV格式的文本
        csv_lines = []
        for row in selected_rows:
            row_data = []
            for col in selected_cols:
                value = rows_data[row].get(col, "")
                # 处理包含逗号或引号的值
                value_str = str(value)
                if ',' in value_str or '"' in value_str or '\n' in value_str:
                    escaped_value = value_str.replace('"', '""')
                    value_str = f'"{escaped_value}"'
                row_data.append(value_str)
            csv_lines.append(','.join(row_data))
        
        csv_text = '\n'.join(csv_lines)
        
        # 创建制表符分隔的文本（用于Excel粘贴）
        tsv_lines = []
        for row in selected_rows:
            row_data = []
            for col in selected_cols:
                value = rows_data[row].get(col, "")
                row_data.append(str(value))
            tsv_lines.append('\t'.join(row_data))
        
        tsv_text = '\n'.join(tsv_lines)
        
        # 复制到剪贴板
        from PySide6.QtGui import QClipboard, QGuiApplication
        clipboard = QGuiApplication.clipboard()
        
        # 设置多种格式的剪贴板数据
        clipboard.setText(csv_text)
        
        # 可选：设置HTML格式
        html_text = "<table>"
        for row in selected_rows:
            html_text += "<tr>"
            for col in selected_cols:
                value = rows_data[row].get(col, "")
                html_text += "<td>" + str(value) + "</td>"
            html_text += "</tr>"
        html_text += "</table>"
        
        mime_data = clipboard.mimeData()
        mime_data.setText(csv_text)
        mime_data.setHtml(html_text)
        
        # 显示状态提示
        QMessageBox.information(self, "复制成功", f"已复制 {len(selected_rows)} 行 {len(selected_cols)} 列数据到剪贴板")
    
    def _paste_selection(self):
        """粘贴内容"""
        # 实现粘贴功能
        pass
    
    def _show_context_menu(self, position):
        """显示右键菜单"""
        if not self._model:
            return
            
        menu = QMenu(self)
        
        # 添加行
        add_row_action = QAction("添加行", self)
        add_row_action.triggered.connect(self._add_row)
        menu.addAction(add_row_action)
        
        # 插入行
        insert_row_action = QAction("插入行", self)
        insert_row_action.triggered.connect(self._insert_row)
        menu.addAction(insert_row_action)
        
        # 删除行
        if self.selectedIndexes():
            delete_row_action = QAction("删除选中行", self)
            delete_row_action.triggered.connect(self._delete_selected_rows)
            menu.addAction(delete_row_action)
        
        # 行状态管理
        if self.selectedIndexes():
            menu.addSeparator()
            
            # 禁用选中行
            disable_rows_action = QAction("禁用选中行", self)
            disable_rows_action.triggered.connect(self._disable_selected_rows)
            menu.addAction(disable_rows_action)
            
            # 启用选中行
            enable_rows_action = QAction("启用选中行", self)
            enable_rows_action.triggered.connect(self._enable_selected_rows)
            menu.addAction(enable_rows_action)
        
        menu.addSeparator()
        
        # 复制
        copy_action = QAction("复制", self)
        copy_action.triggered.connect(self._copy_selection)
        menu.addAction(copy_action)
        
        # 粘贴
        paste_action = QAction("粘贴", self)
        paste_action.triggered.connect(self._paste_selection)
        menu.addAction(paste_action)
        
        menu.addSeparator()
        
        # 全选
        select_all_action = QAction("全选", self)
        select_all_action.triggered.connect(self.selectAll)
        menu.addAction(select_all_action)
        
        # 显示菜单
        menu.exec_(self.mapToGlobal(position))
    
    def _add_row(self):
        """添加行"""
        # 发送信号给主窗口处理添加行
        # 注意：这里仍然保留信号发射，以保持与现有代码的兼容性
        # 在完全迁移到事件驱动架构后，可以直接调用数据管理器的方法
        self.add_row_requested.emit()
    
    def _insert_row(self):
        """插入行"""
        if not self._model:
            return
            
        # 获取当前选中的行
        selected_rows = self.get_selected_rows()
        current_row = selected_rows[0] if selected_rows else 0
        total_rows = self._model.rowCount()
        
        # 创建插入行对话框
        from frontend.insert_row_dialog import InsertRowDialog
        from PySide6.QtWidgets import QDialog
        dialog = InsertRowDialog(current_row, total_rows, self)
        if dialog.exec() == QDialog.Accepted:
            result = dialog.get_row_info()
            if result:
                count, position, fill_mode_index = result
                
                # 获取表头以创建空行数据
                data, headers = self._model._data_manager.get_data()
                empty_row = [""] * len(headers)
                
                # 根据填充模式创建行数据
                if fill_mode_index == 1 and position > 0:  # 复制上一行
                    if position - 1 < len(data):
                        row_data = data[position - 1].copy()
                    else:
                        row_data = empty_row
                elif fill_mode_index == 2 and position < len(data):  # 复制当前行
                    row_data = data[position].copy()
                else:  # 空白值或智能默认值
                    row_data = empty_row
                
                # 发送插入行信号，让主窗口统一处理
                # 注意：这里仍然保留信号发射，以保持与现有代码的兼容性
                # 在完全迁移到事件驱动架构后，可以直接调用数据管理器的方法
                self.insert_row_requested.emit(position, row_data)
    
    def _disable_selected_rows(self):
        """禁用选中的行"""
        selected_rows = self.get_selected_rows()
        if selected_rows:
            # 过滤掉已经禁用的行
            enabled_rows = [row for row in selected_rows if not self._model.is_row_disabled(row)]
            if enabled_rows:
                # 注意：这里仍然保留信号发射，以保持与现有代码的兼容性
                # 在完全迁移到事件驱动架构后，可以直接调用数据管理器的方法
                self.row_status_changed.emit(enabled_rows, 'disable')
    
    def _enable_selected_rows(self):
        """启用选中的行"""
        selected_rows = self.get_selected_rows()
        if selected_rows:
            # 过滤出已经禁用的行
            disabled_rows = [row for row in selected_rows if self._model.is_row_disabled(row)]
            if disabled_rows:
                # 注意：这里仍然保留信号发射，以保持与现有代码的兼容性
                # 在完全迁移到事件驱动架构后，可以直接调用数据管理器的方法
                self.row_status_changed.emit(disabled_rows, 'enable')
    
    def get_selected_rows(self) -> list:
        """获取选中的行"""
        selected_rows = set()
        for index in self.selectedIndexes():
            if self._proxy_model:
                source_row = self._proxy_model.mapToSource(index).row()
            else:
                source_row = index.row()
            selected_rows.add(source_row)
        return sorted(list(selected_rows))
    
    def get_selected_columns(self) -> list:
        """获取选中的列"""
        selected_columns = set()
        for index in self.selectedIndexes():
            if self._proxy_model:
                source_col = self._proxy_model.mapToSource(index).column()
            else:
                source_col = index.column()
            selected_columns.add(source_col)
        return sorted(list(selected_columns))
    
    def set_column_range(self, column_range: List[int]):
        """设置显示的列范围"""
        self._column_range = column_range
        if self._model:
            self._model.set_column_range(column_range)
            self._adjust_column_widths()
            
    def get_column_range(self) -> List[int]:
        """获取显示的列范围"""
        return self._column_range.copy()
        
    def refresh_view(self):
        """刷新视图"""
        if self._model:
            self._model.refresh_data()
            self._adjust_column_widths()
